<template>
  <div ref="ganttContainer" style="width: 100%; height: 600px"></div>
</template>

<script>
import { gantt } from 'dhtmlx-gantt';
import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';
import axios from 'axios'; // 假设使用 axios 发送请求

export default {
  name: 'GanttChart',
  props: {
    apiUrl: {
      type: String,
      default: '', // 默认为空，表示不自动发送到后端
    },
    autoSave: {
      type: Boolean,
      default: false, // 是否自动保存到后端
    },
    initialTasks: {
      type: Object,
      default: () => {
        const getFormattedDate = offset => {
          const date = new Date();
          date.setDate(date.getDate() + offset);
          return date.toISOString().split('T')[0]; // 返回YYYY-MM-DD格式
        };

        return {
          data: [
            {
              id: 1,
              text: '项目任务',
              start_date: getFormattedDate(0),
              duration: 5,
              progress: 0.4,
            },
            {
              id: 2,
              text: '子任务1',
              start_date: getFormattedDate(0),
              duration: 3,
              parent: 1,
              progress: 0.6,
            },
            {
              id: 3,
              text: '子任务2',
              start_date: getFormattedDate(3),
              duration: 2,
              parent: 1,
              progress: 0.5,
            },
          ],
          links: [{ id: 1, source: 2, target: 3, type: 0 }],
        };
      },
    },
  },
  data() {
    return {
      updatedTasksData: null, // 存储拖拽后的数据
    };
  },
  mounted() {
    // 检查dhtmlx-gantt是否加载
    if (!window.gantt) {
      console.error('dhtmlx-gantt未正确加载');
      return;
    }

    // 检查容器元素是否存在
    if (!this.$refs.ganttContainer) {
      console.error('甘特图容器元素未找到');
      return;
    }

    // 初始化甘特图
    try {
      this.initGantt();
      console.log('甘特图初始化完成');

      // 测试拖拽功能
      setTimeout(() => {
        const taskElements = document.querySelectorAll('.gantt_task_line');
        console.log('找到的任务元素:', taskElements.length);

        if (taskElements.length > 0) {
          console.log(
            '第一个任务元素样式:',
            window.getComputedStyle(taskElements[0])
          );
        }
      }, 1000);
    } catch (e) {
      console.error('甘特图初始化失败:', e);
    }
  },
  beforeUnmount() {
    if (gantt && gantt.destroy) {
      gantt.destroy();
    }
  },
  methods: {
    initGantt() {
      // 配置甘特图日期格式
      gantt.config.date_format = '%Y-%m-%d'; // 设置日期格式为YYYY-MM-DD
      gantt.config.date_grid = '%Y-%m-%d'; // 设置表格中的日期格式
      gantt.config.xml_date = '%Y-%m-%d'; // 设置数据解析的日期格式

      // 设置时间尺度
      // 配置时间格式
      gantt.config.scale_height = 50; // 设置时间轴高度

      // 配置时间尺度
      gantt.config.scales = [
        { unit: 'month', step: 1, format: '%Y年%m月' },
        { unit: 'week', step: 1, format: '第%W周' },
        {
          unit: 'day',
          step: 1,
          format: function (date) {
            // 自定义格式化函数，确保月份显示为两位数
            const month = date.getMonth() + 1; // getMonth()返回0-11
            const day = date.getDate();
            const monthStr = month < 10 ? '0' + month : month;
            const dayStr = day < 10 ? '0' + day : day;

            // 获取星期几
            const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
            const weekday = weekdays[date.getDay()];

            return monthStr + '月' + dayStr + '日 周' + weekday;
          },
          css: function (date) {
            if (!gantt.isWorkTime(date)) {
              return 'weekend';
            }
            return '';
          },
        },
      ];

      // 配置工作时间
      gantt.config.work_time = true; // 启用工作时间
      gantt.setWorkTime({ hours: ['8:00-12:00', '13:00-17:00'] }); // 设置工作时间
      gantt.setWorkTime({ day: 0, hours: false }); // 周日不工作
      gantt.setWorkTime({ day: 6, hours: false }); // 周六不工作

      // 配置时间轴样式
      gantt.templates.timeline_cell_class = function (task, date) {
        if (!gantt.isWorkTime(date)) {
          return 'weekend';
        }
        return '';
      };

      // 配置日期格式化函数
      const formatDate = function (date) {
        const year = date.getFullYear();
        const month = date.getMonth() + 1;
        const day = date.getDate();
        const monthStr = month < 10 ? '0' + month : month;
        const dayStr = day < 10 ? '0' + day : day;
        return year + '年' + monthStr + '月' + dayStr + '日';
      };

      // 配置表格列
      gantt.config.columns = [
        {
          name: 'text',
          label: '任务名称',
          tree: true,
          width: 200,
          resize: true, // 启用宽度调整
          min_width: 100, // 最小宽度
        },
        {
          name: 'start_date',
          label: '开始时间',
          align: 'center',
          width: 120,
          resize: true, // 启用宽度调整
          min_width: 80,
          template: function (task) {
            return formatDate(task.start_date);
          },
        },
        {
          name: 'duration',
          label: '持续时间',
          align: 'center',
          width: 80,
          resize: true, // 启用宽度调整
          min_width: 50,
          template: function (task) {
            return task.duration + '天';
          },
        },
        {
          name: 'progress',
          label: '进度',
          align: 'center',
          width: 80,
          resize: true, // 启用宽度调整
          min_width: 50,
          template: function (task) {
            return Math.round(task.progress * 100) + '%';
          },
        },
      ];

      // 启用列宽度调整
      gantt.config.grid_resize = true;
      gantt.config.keep_grid_width = false; // 允许表格宽度变化
      gantt.config.grid_elastic_columns = true; // 弹性列宽

      // 配置任务日期显示格式
      gantt.templates.task_date = function (date) {
        return formatDate(date);
      };

      // 配置任务提示显示格式
      gantt.templates.tooltip_text = function (start, end, task) {
        return `<b>任务:</b> ${task.text}<br/>
                <b>开始:</b> ${formatDate(start)}<br/>
                <b>结束:</b> ${formatDate(end)}<br/>
                <b>进度:</b> ${Math.round(task.progress * 100)}%`;
      };

      // 配置表格中的日期格式
      gantt.templates.grid_date_format = function (date) {
        return formatDate(date);
      };

      // 配置任务详情中的日期格式
      gantt.templates.task_time = function (start, end) {
        return formatDate(start) + ' - ' + formatDate(end);
      };

      // 启用所有拖拽相关配置
      // gantt.config.drag_mode = "resize,progress,move"; // 允许调整大小、进度和移动
      // gantt.config.drag_links = true; // 允许链接拖拽
      // gantt.config.drag_progress = true; // 允许进度条拖拽
      // gantt.config.drag_resize = true; // 允许任务调整大小
      // gantt.config.drag_move = true; // 允许任务移动
      // gantt.config.drag_timeline = true; // 允许在时间轴上拖动

      // // 设置拖拽精度
      // gantt.config.round_dnd_dates = true; // 拖拽时对齐到最近的日期
      // gantt.config.drag_lightbox = false; // 禁用拖拽时的lightbox

      // // 允许通过拖拽创建任务链接
      // gantt.config.drag_links = true;
      // gantt.config.show_links = true;

      // // 设置任务可编辑
      // gantt.config.readonly = false;
      // gantt.config.editable_grid = true;

      // // 设置拖拽时的约束
      // gantt.config.drag_project = true; // 允许拖拽项目
      // gantt.config.drag_multiple = true; // 允许多选拖拽

      // 设置任务调整大小的最小单位（以小时为单位）
      gantt.config.min_duration = 1 * 24 * 60 * 60 * 1000; // 1天

      // 设置日期格式化函数
      gantt.templates.tooltip_text = function (start, end, task) {
        return `<b>任务:</b> ${task.text}<br/>
                <b>开始:</b> ${gantt.templates.tooltip_date_format(start)}<br/>
                <b>结束:</b> ${gantt.templates.tooltip_date_format(end)}<br/>
                <b>进度:</b> ${Math.round(task.progress * 100)}%`;
      };

      // 初始化甘特图
      gantt.init(this.$refs.ganttContainer);

      // 解析任务数据
      gantt.parse(this.initialTasks);

      // 初始化后保存初始数据
      this.updatedTasksData = gantt.serialize();

      // 监听任务拖拽结束事件
      // 监听任务拖拽开始事件
      gantt.attachEvent('onBeforeTaskDrag', (id, mode) => {
        console.log('开始拖拽任务:', id, '模式:', mode);
        return true; // 返回true允许拖拽
      });

      // 监听任务拖拽过程中的事件
      gantt.attachEvent('onTaskDrag', (id, mode, task, original) => {
        console.log('拖拽中:', id, mode, task, original);
        // 在拖拽过程中实时更新数据
        this.updatedTasksData = gantt.serialize();
        // 触发自定义事件，将更新后的数据发送给父组件
        this.$emit('task-updated', this.updatedTasksData);
        return true;
      });

      // 监听任务拖拽结束事件
      gantt.attachEvent('onAfterTaskDrag', (id, mode, e) => {
        console.log('拖拽结束:', id, mode, e);

        // 获取并保存更新后的数据
        this.updatedTasksData = gantt.serialize();
        // 触发自定义事件，通知父组件数据已更新
        this.$emit('task-drag-end', this.updatedTasksData);

        // 如果设置了自动保存，则发送到后端
        if (this.autoSave && this.apiUrl) {
          this.sendDataToBackend(this.updatedTasksData);
        }
      });

      // 监听任务链接创建事件
      gantt.attachEvent('onLinkCreated', link => {
        console.log('链接创建:', link);
        this.updatedTasksData = gantt.serialize();
        this.$emit('link-created', this.updatedTasksData);
        return true;
      });

      // 监听任务更新事件
      gantt.attachEvent('onAfterTaskUpdate', (id, task) => {
        console.log('任务更新:', id, task);
        this.updatedTasksData = gantt.serialize();
        this.$emit('task-updated', this.updatedTasksData);
      });

      // 监听任务移动事件
      gantt.attachEvent('onTaskDblClick', (id, e) => {
        console.log('任务双击:', id, e);
        return true;
      });
    },
    // 发送数据到后端
    sendDataToBackend(data) {
      if (!this.apiUrl) {
        console.warn('未提供API URL，无法保存数据');
        this.$emit('save-error', new Error('未提供API URL'));
        return;
      }

      console.log('发送的数据：', data);

      axios
        .post(this.apiUrl, data)
        .then(response => {
          console.log('数据已成功发送到后端', response);
          this.$emit('save-success', response.data);
        })
        .catch(error => {
          console.error('发送数据到后端时出错', error);
          this.$emit('save-error', error);
        });
    },

    // 获取当前甘特图数据
    getCurrentData() {
      return this.updatedTasksData || gantt.serialize();
    },

    // 导出数据为JSON字符串
    exportToJSON() {
      return JSON.stringify(this.getCurrentData(), null, 2);
    },

    // 手动保存数据到后端
    save() {
      const currentData = this.getCurrentData();
      this.sendDataToBackend(currentData);
      return currentData;
    },

    // 重置为初始数据
    reset() {
      gantt.clearAll();
      gantt.parse(this.initialTasks);
      this.updatedTasksData = gantt.serialize();
      this.$emit('data-reset', this.updatedTasksData);
    },
  },
};
</script>

<style>
/* 非工作时间的样式 */
.weekend {
  background-color: #f8f8f8;
}

/* 甘特图任务样式 */
.gantt_task_line {
  border-radius: 4px;
}

/* 进度条样式 */
.gantt_task_progress {
  background-color: #4caf50;
  opacity: 0.6;
}

/* 里程碑样式 */
.gantt_milestone {
  background-color: #ff5722;
  border-color: #ff5722;
}

/* 项目样式 */
.gantt_project {
  background-color: #2196f3;
  border-color: #2196f3;
}

/* 链接样式 */
.gantt_link_arrow {
  border-color: #607d8b;
}

/* 确保任务元素可拖拽 */
.gantt_task_line {
  cursor: move;
  user-select: none;
  touch-action: none;
}

/* 拖拽时的样式 */
.gantt_drag_marker {
  z-index: 1000;
}

/* 确保时间轴可交互 */
.gantt_grid_data,
.gantt_task_scroll {
  pointer-events: auto;
}

/* 确保任务行可交互 */
.gantt_task_row {
  pointer-events: auto;
}

/* 确保任务内容区域可交互 */
.gantt_task_content {
  pointer-events: auto;
}
</style>
